package com.skyline.attraction.controller;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import net.imagine.core.ResultState;
import net.imagine.provider.skyline.ImageCropResult;
import net.imagine.provider.skyline.ImageCutter;
import net.imagine.provider.skyline.SkylineImageCropTask;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.skyline.attraction.model.Attraction;
import com.skyline.attraction.model.AttractionFeature;
import com.skyline.attraction.model.AttractionRefrence;
import com.skyline.attraction.service.AttractionFeatureService;
import com.skyline.attraction.service.AttractionRefrenceService;
import com.skyline.attraction.service.AttractionService;
import com.skyline.attraction.type.AttractionRefrenceType;
import com.skyline.attraction.type.SiteType;
import com.skyline.base.controller.BaseController;
import com.skyline.base.exception.NotLoginException;
import com.skyline.base.exception.OperateFailedException;
import com.skyline.base.type.ResourceType;
import com.skyline.common.bean.Page;
import com.skyline.common.util.ViewPaths;
import com.skyline.user.model.Fan;
import com.skyline.user.model.User;
import com.skyline.user.service.FanService;
import com.skyline.wo.model.Album;
import com.skyline.wo.model.Photo;
import com.skyline.wo.service.AlbumService;

@RequestMapping("/attraction")
@Controller
public class AttractionController extends BaseController {
	// private static final Log LOGGER =
	// LogFactory.getLog(AttractionController.class);
	@Autowired
	private AttractionService attractionService;
	@Autowired
	private AttractionRefrenceService attractionRefrenceService;
	@Autowired
	private FanService fanService;
	// @Autowired
	// private ArticleService articleService;
	@Autowired
	private AttractionFeatureService attractionFeatureService;
	@Autowired
	private AlbumService albumService;

	@Autowired
	private ImageCutter crop;
	@Value("${imagine.protraitSize}")
	private int portraitSize;
	@Value("${imagine.localStorePath}")
	private String basePath;

	private @Value("${attraction.list.pagesize}")
	int listAttractionPageSize;
	
	private @Value("${attraction.view.featuresize}")
	int featureSize;
	
	private @Value("${attraction.view.refrencesize}")
	int refrenceSize;

	/**
	 * 添加景点用请求函数
	 * 
	 * @return
	 */
	@RequestMapping(value = "/discovery", method = RequestMethod.GET)
	public ModelAndView discovery() {
		checkAndReturnLoginedUser();
		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_DISCOVERY);
		return view;
	}

	/**
	 * 是否存在同名景点
	 * 
	 * @param attractionName
	 * @return
	 */
	@RequestMapping(value = "/isExist", method = { RequestMethod.POST, RequestMethod.GET })
	public @ResponseBody
	Boolean isNameExit(@RequestParam("name") String attractionName) {
		try {
			return attractionService.isExist(attractionName);
		} catch (Exception e) {
			return Boolean.FALSE;
		}

	}

	/**
	 * 添加景点递交请求函数
	 */
	@RequestMapping(value = "/discovery", method = RequestMethod.POST)
	public ModelAndView discovery(Attraction attraction) {
		User user = checkAndReturnLoginedUser();

		String errMsg = validateForm("discoveryForm", attraction);
		ModelAndView returnView = discovery();
		if (errMsg != null) {
			return processValidationErrors("errMsg", errMsg, returnView);
		}

		if (attractionService.isExist(attraction.getName())) {
			returnView.addObject("errMsg", "对不起，已存在同名景点！");
			return returnView;
		}
		Long attractionId = null;
		try {
			attractionId = attractionService.discoveryAttraction(user, attraction);
		} catch (Exception e) {
			if (attractionId == null || attractionId == 0L) {
				returnView.addObject("errMsg", "对不起，添加景点失败！");
				return returnView;
			}
		}
		String url = buildRecirectPath("/attraction/upPortrait/" + attractionId);
		return new ModelAndView(new RedirectView(url));
	}

	@RequestMapping(value = "/upPortrait/{attractionId}", method = RequestMethod.GET)
	public ModelAndView uploadPortrait(@PathVariable("attractionId") Long attractionId) {
		User user = checkAndReturnLoginedUser();
		Attraction attraction = attractionService.getAttractionForChange(attractionId, user.getId());
		Album portraitAlbum = albumService.getUserPortraitAlbum(attractionId);
		Photo portraitPhoto = albumService.getUserCurrentPortraitPhoto(attractionId);

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_EDITPORTRAIT);
		view.addObject("portraitAlbumId", portraitAlbum.getId());
		view.addObject("portrait", portraitPhoto);
		view.addObject("attractionInfo", attraction);
		return view;
	}

	@RequestMapping(value = "/upPortrait/{attractionId}", method = RequestMethod.POST)
	public ModelAndView uploadPortrait(@PathVariable("attractionId") Long attractionId, Integer x, Integer y,
			Integer size, String submitToken) {
		User user = checkAndReturnLoginedUser();

		String errMsg = this.validateForm("portraitUploadForm", submitToken);
		if (errMsg != null) {
			return processValidationErrors("errMsg", errMsg, uploadPortrait(attractionId));
		}
		Attraction attraction = attractionService.getAttractionForChange(attractionId, user.getId());
		attractionId = attraction.getId();
		Photo portrait = albumService.getUserCurrentPortraitPhoto(attractionId);
		if (portrait == null) {
			throw new OperateFailedException("不存在当前图片，无法剪切");
		}

		long albumId = portrait.getAlbumId();

		String smallFile = portrait.getSmallFile();
		String ext = portrait.getExt();
		String remoteFileKey = smallFile + '.' + ext;

		SkylineImageCropTask cropTask = new SkylineImageCropTask(remoteFileKey, portraitSize);
		cropTask.setAlbumId(albumId);
		cropTask.setUserId(attractionId);
		cropTask.setOffsetX(x);
		cropTask.setOffsetY(y);
		cropTask.setCropSize(size);
		ImageCropResult cropResult;
		try {
			cropResult = crop.processImage(basePath, cropTask);
		} catch (IOException e) {
			throw new OperateFailedException("无法剪切图片");
		}
		if (cropResult == null || cropResult.getResultState() != ResultState.SUCCESS) {
			throw new OperateFailedException("无法剪切图片，原因：" + (cropResult == null ? null : cropResult.getResultState()));
		}
		String portraitFile = cropResult.getFileKey();

		attractionService.updateAttractionPortrait(attractionId, portraitFile);

		String url = buildRecirectPath("/attraction/view/" + attractionId);
		ModelAndView view = new ModelAndView(new RedirectView(url));
		return view;
	}

	/**
	 * 重新编辑景点请求函数
	 * 
	 * @param attractionId
	 * @return
	 */
	@RequestMapping(value = "/edit/{attractionId}", method = RequestMethod.GET)
	public ModelAndView editAttraction(@PathVariable("attractionId") Long attractionId) {
		User user = checkAndReturnLoginedUser();

		Attraction attraction = attractionService.getAttractionForChange(attractionId, user.getId());

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_EDIT);
		view.addObject("attractionInfo", attraction);
		return view;
	}

	/**
	 * 重新编辑景点请求函数
	 * 
	 * @param attractionId
	 * @return
	 */
	@RequestMapping(value = "/edit/{attractionId}", method = RequestMethod.POST)
	public ModelAndView editAttraction(@PathVariable("attractionId") Long attractionId, Attraction attraction) {
		User user = checkAndReturnLoginedUser();

		String errMsg = validateForm("discoveryForm", attraction);
		ModelAndView returnView = editAttraction(attractionId);
		if (errMsg != null) {
			return processValidationErrors("errMsg", errMsg, returnView);
		}

		try {
			attractionService.updateAttractionInfo(attraction, user.getId());
		} catch (OperateFailedException e) { // 对于同名特殊处理
			if ("对不起，已存在同名景点！".equals(e.getMessage())) {
				returnView.addObject("errMsg", "对不起，已存在同名景点！");
				return returnView;
			} else {
				throw new OperateFailedException(e);
			}

		}

		String url = buildRecirectPath("/attraction/view/" + attractionId);
		ModelAndView view = new ModelAndView(new RedirectView(url));
		return view;
	}

	/**
	 * 景点主页请求显示函数
	 * 
	 * @param attractionId
	 * @return
	 */
	@RequestMapping(value = "/view/{attractionId}", method = RequestMethod.GET)
	public ModelAndView viewAttraction(@PathVariable("attractionId") Long attractionId,
			@RequestParam(value = "type", required = false) AttractionRefrenceType type) {

		boolean addVisitCount = !checkVisitedAndLogFootprint(attractionId, ResourceType.ATTRACTION);
		Long viewerId = getViewerId();
		
		Attraction attraction = attractionService.viewAttraction(attractionId, viewerId, addVisitCount);

		List<AttractionFeature> featureList = attractionFeatureService.listSomeFeatureOfAttraction(attractionId, featureSize);

		List<AttractionRefrence> refList = attractionRefrenceService.listSomeRefrencesOfAttraction(attractionId, type, refrenceSize);
		
		boolean isIdol = fanService.isFan(attractionId, viewerId);
		List<Fan> fanList = fanService.listFans(attractionId, null);

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_VIEW);
		view.addObject("attraction", attraction);
		if (CollectionUtils.isEmpty(featureList)) {
			view.addObject("featureList", null);
		} else {
			view.addObject("featureList", featureList);
		}
		view.addObject("isIdol", isIdol);
		view.addObject("refList", refList);
		view.addObject("fanList", fanList);
		view.addObject("type", type);
		return view;

	}

	/**
	 * 根据国家分类显示请求函数
	 * 
	 * @param country
	 * @param province
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView listAttraction(@RequestParam(value = "siteId", required = false) String siteId,
			@RequestParam(value = "siteType", required = false) SiteType siteType, Page page) {
		page.setSize(listAttractionPageSize);

		List<Attraction> attractionList = attractionService.listAttractions(siteId, siteType, null, page);

		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_LIST);
		view.addObject("attractionList", attractionList);
		view.addObject("page", page);
		view.addObject("siteType", siteType);
		view.addObject("siteId", siteId);
		return view;

	}

	@RequestMapping(value = "/modifyIntro/{attractionId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, Object> modifyAttractionIntroduction(@PathVariable("attractionId") Long attractionId,
			String introduction) {
		try {
			User user = checkAndReturnLoginedUser();

			String errMsg = validateForm("introductionOnlyForm", introduction);
			if (errMsg != null) {
				return toJsonMap(false, errMsg, true);
			}

			attractionService.updateAttractionIntroduction(attractionId, introduction, user.getId());
			return toJsonMap(true, "修改景点简介成功！", true);
		} catch (NotLoginException e) {
			return toJsonMap(false, "您已登录超时，请重新登录", false);
		} catch (Exception e) {
			return toJsonMap(false, "修改景点简介失败！", true);
		}
	}

	@RequestMapping(value = "/map/{attractionId}", method = RequestMethod.GET)
	public ModelAndView viewMap(@PathVariable("attractionId") Long attractionId) {
		ModelAndView view = new ModelAndView(ViewPaths.ATTRACTION_MAP);
		Attraction attraction = attractionService.getNormalAttraction(attractionId);
		view.addObject("attraction", attraction);
		return view;
	}

}
